﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using IndieStudio.BugsBang.Game;

///Developed By Indie Studio
///https://assetstore.unity.com/publishers/9268
///www.indiestd.com
///info@indiestd.com

namespace IndieStudio.BugsBang.Utility
{
	[DisallowMultipleComponent]
	public class LevelsManager : MonoBehaviour
	{
		/// <summary>
		/// The list of levels.
		/// </summary>
		public List<Level> levels = new List<Level> ();

		/// <summary>
		/// Whether to enable the test mode or not.
		/// </summary>
		public bool testMode;

		/// <summary>
		/// A static instance of this class.
		/// </summary>
		public static LevelsManager instance;

		// Use this for initialization
		void Awake ()
		{
			if (Application.isPlaying) {
				if (instance == null) {
					instance = this;
					DontDestroyOnLoad (gameObject);
				} else {
					Destroy (gameObject);
				}

				Init ();
			}
		}

		/// <summary>
		/// Get the current level.
		/// </summary>
		/// <returns>The current level.</returns>
		public Level GetCurrentLevel(){
			int index = IndieStudio.BugsBang.Game.Level.SelectedLevelID - 1;

			if (index > -1 && index < levels.Count) {
				return levels [index];
			}

			return null;
		}

		/// <summary>
		/// Init this instance.
		/// </summary>
		private void Init ()
		{
			Debug.Log ("Loading data of the levels");

			bool lastReachedDetermined = false;

			for (int i = 0; i < levels.Count; i++) {
				levels [i].ID = i+1;
				levels [i].isLocked = DataManager.IsLevelLocked (levels [i].ID);
				levels [i].starsNumber = DataManager.GetLevelStars (levels [i].ID);
				levels [i].score = DataManager.GetLevelScore (levels [i].ID);

				if (levels [i].ID == 1 || testMode) {
					levels [i].isLocked = false;
				}

				if (!testMode && !lastReachedDetermined) {
					//Determine the Last reached level
					DataManager.DetermineLastReachedLevel(levels [i]);

					lastReachedDetermined = levels [i].isLastRreached;
				}
			}
		}

		/// <summary>
		/// Get the collected stars for all levels.
		/// </summary>
		/// <returns>The collected stars.</returns>
		public int GetCollectedStars(){
			int cs = 0;
			foreach (Level shape in levels) {
				if (shape.starsNumber == Level.StarsNumber.ONE) {
					cs+=1;
				} else if (shape.starsNumber == Level.StarsNumber.TWO) {
					cs+=2;
				} else if (shape.starsNumber == Level.StarsNumber.THREE) {
					cs+=3;
				}
			}
			return cs;
		}

		/// <summary>
		/// Reset the levels.
		/// </summary>
		public void ResetLevels(){
			for (int i = 0; i < levels.Count; i++) {
				levels [i].Reset ();
				//Save reset changes
				DataManager.SaveLevelLockedStatus (levels [i].ID, levels [i].isLocked);
				DataManager.SaveLevelScore (levels [i].ID, levels [i].score);
				DataManager.SaveLevelStars (levels [i].ID, levels [i].starsNumber);
			}
		}

		[System.Serializable]
		public class Level
		{
			//The targets list
			public List<Target> targets = new List<Target> ();
			//The paths list
			public List<Path> paths = new List<Path> ();
			//The id of the level
			[HideInInspector]
			public int ID;
			//Whether the random mode of level is enabled or not
			//If true, the objects will be instantiated randomly in the paths of the level
			public bool randomMode = true;
			//Whether the level is the last reached or not
			[HideInInspector]
			public bool isLastRreached;
			[HideInInspector]
			//Whether the level is locked or not
			public bool isLocked = true;
			//Number of stars (stars rating)
			[HideInInspector]
			public StarsNumber starsNumber = StarsNumber.ZERO;
			//Level score
			[HideInInspector]
			public int score = 0;
			/* The stars time period in seconds.
			Example if value equals 30 then 0 -> 30 seconds = 3 stars , 30 -> 60 = 2 stars , 60 -> 90 = 1 stars ,otherwise zero*/
			public int starsTimePeriod = 30;
			//Number of lives in the level
			public int lives = 3;

			// Reset this instance.
			public void Reset(){
				if (ID == 1) {
					isLastRreached = true;
					isLocked = false;
				} else {
					isLocked = true;
					isLastRreached = false;
				}

				starsNumber = StarsNumber.ZERO;
				score = 0;
			}

			public enum StarsNumber
			{
				ZERO,
				ONE,
				TWO,
				THREE
			}

			[System.Serializable]
			public class Path{
				//You can add more attributes for the path
				public bool showContents = true;
				public IndieStudio.BugsBang.Game.Path value;
				public List<PathObject> pathObjects = new List<PathObject>();
			}

			[System.Serializable]
			public class Target{
				public bool showContents = true;
				public int count = 10;
				public PathObject pathObject;
			}
		}
	}
}